//************************************************************************
/// <copyrigth>2024-2025 Corporation.All Rights Reserved</copyrigth>
/// <author>tangyingzhong</author>
/// <contact>tangyz114987@outlook.com</contact>
/// <version>v1.0.0</version>
/// <describe>
/// Cross-Platform json parser and builder
///</describe>
/// <date>2024/2/4</date>
///***********************************************************************
#ifndef JSON_H
#define JSON_H

#include <string>
#include <vector>
#include "ModuleLoader/ModuleConfig.h"

namespace SystemTool
{
    class CLASS_ITEM JsonDocument
    {
    public:
        // Empty construction
        JsonDocument();

        // Destruct json
        ~JsonDocument();

        // Construct with another json
        JsonDocument(JsonDocument& other);

        // Copy construction
        JsonDocument(const JsonDocument& other);

        // Assigment of json
        JsonDocument& operator=(const JsonDocument& other);

        // Parse from std::string
        static JsonDocument FromJson(std::string strJsonData);

        // Parse from json file
        static JsonDocument FromJsonFile(std::string strJsonFilePath);

        // Dump to json std::string
        std::string ToJson();

        // Dump to json file
        bool ToJsonFile(std::string strJsonFilePath);

        // Is array
        bool IsArray();

        // Is obj
        bool IsObject();

        // Is null json
        bool IsNull();

        // Is empty json
        bool IsEmpty();

        // Is contain the key
        bool IsContainKey(std::string strKey);

        // Get all root's keys
        bool GetAllKeys(std::vector<std::string>& vKeyTable);

        // Set obj
        bool SetKeyValue(std::string strKey, JsonDocument &obj);

        // Set std::string
        bool SetKeyValue(std::string strKey, std::string strData);

        // Set std::string
        bool SetKeyValue(std::string strKey, const char* pData);

        // Set int
        bool SetKeyValue(std::string strKey, int iValue);

        // Set unsigned int
        bool SetKeyValue(std::string strKey, unsigned int uValue);

        // Set long
        bool SetKeyValue(std::string strKey, long lValue);

        // Set long long
        bool SetKeyValue(std::string strKey, long long llValue);

        // Set unsigend long long
        bool SetKeyValue(std::string strKey, unsigned long long ullValue);

        // Set double
        bool SetKeyValue(std::string strKey, double dValue);

        // Set bool
        bool SetKeyValue(std::string strKey, bool bValue);

        // Set short 
        bool SetKeyValue(std::string strKey, short sValue);

        // Set unsigned short
        bool SetKeyValue(std::string strKey, unsigned short usValue);

        // Append the obj
        void Append(JsonDocument &obj);

        // Append std::string
        void Append(std::string strData);

        // Append std::string
        void Append(const char* pData);

        // Append the int
        void Append(int iValue);

        // Append the unsigend int
        void Append(unsigned int uiValue);

        // Append the long 
        void Append(long lValue);

        // Append the long long
        void Append(long long llValue);

        // Append the unsigned long long
        void Append(unsigned long long ullValue);

        // Append the double 
        void Append(double dValue);

        // Appened the bool
        void Append(bool bValue);

        // Get size of json array
        int Size();

        // Get obj
        JsonDocument GetKeyValue(std::string strKey);

        // Get obj
        JsonDocument GetKeyValue(const char* pKey);

        // Get array element
        JsonDocument operator[](int iIndex);

        // Get data type
        const std::type_info& GetDataType();

        // Is std::string
        bool IsString();

        // Is short
        bool IsShort();

        // Is unsigned short
        bool IsUShort();

        // Is int
        bool IsInt();

        // Is uint
        bool IsUint();

        // Is long 
        bool IsLong();

        // Is unsigned long
        bool IsULong();

        // Is long long
        bool IsLongLong();

        // Is unsigned long long
        bool IsULongLong();

        // Is double
        bool IsDouble();

        // Is bool
        bool IsBool();

        // To std::string
        std::string ToString();

        // To short
        short ToShort();

        // To unsigned short
        unsigned short ToUnShort();

        // To int
        int ToInt();

        // To uint
        unsigned int ToUInt();

        // To long 
        long ToLong();

        // To unsigned long 
        unsigned long ToUnLong();

        // To long long
        long long ToLongLong();

        // To unsigned long long
        unsigned long long ToUnLongLong();

        // To double
        double ToDouble();

        // To bool 
        bool ToBool();
        
        // Get err msg
        std::string GetErrMsg();

    private:
        // Set err msg
        void SetErrMsg(std::string strMsg);

    private:
        // Saving parsing obj
        void* m_pJsonObj;

        // Saving obj
        void* m_pJsonDoc;

        // Saving arr
        void* m_pJsonArr;

        // Err msg
        std::string* m_pErrMsg;
    };
};

#endif // JSON_H
